package com.immediatus.engine.modifier;

import com.immediatus.engine.contracts.IModifier;
import com.immediatus.util.SmartList;

public abstract class BaseModifier<T> implements IModifier<T>{

    private boolean _finished;

    private boolean _removeWhenFinished = true;
    private final SmartList<IModifierListener<T>> _listeners = new SmartList<IModifierListener<T>>(2);

    public BaseModifier(){
    }

    public BaseModifier(final IModifierListener<T> listener_){
        this.addModifierListener(listener_);
    }

    @Override
    public boolean isFinished(){
        return this._finished;
    }

    protected void setFinished(boolean finished_){
        _finished = finished_;
    }

    @Override
    public final boolean isRemoveWhenFinished(){
        return this._removeWhenFinished;
    }

    @Override
    public final void setRemoveWhenFinished(final boolean removeWhenFinished_){
        this._removeWhenFinished = removeWhenFinished_;
    }

    @Override
    public void addModifierListener(final IModifierListener<T> listener_){
        if (listener_ != null){
            this._listeners.add(listener_);
        }
    }

    @Override
    public boolean removeModifierListener(final IModifierListener<T> listener_){
        return listener_ != null && this._listeners.remove(listener_);
    }

    @Override
    public abstract IModifier<T> deepCopy();

    protected void onModifierStarted(final T item_){
        final SmartList<IModifierListener<T>> modifierListeners = this._listeners;
        final int modifierListenerCount = modifierListeners.size();
        for (int i = modifierListenerCount - 1; i >= 0; i--){
            modifierListeners.get(i).onModifierStarted(this, item_);
        }
    }

    protected void onModifierFinished(final T item_){
        final SmartList<IModifierListener<T>> modifierListeners = this._listeners;
        final int modifierListenerCount = modifierListeners.size();
        for (int i = modifierListenerCount - 1; i >= 0; i--){
            modifierListeners.get(i).onModifierFinished(this, item_);
        }
    }
}
